package com.autoscript.web;

import com.autoscript.ISystemConstant;
import com.autoscript.service.UserMenuService;
import com.autoscript.utils.SessionMap;
import com.autoscript.vo.LoginVo;
import com.dfhc.util.StringHelper;
import com.dfhc.util.ConvertHelper;
import com.wf.captcha.SpecCaptcha;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.autoscript.vo.UserVo;
import com.autoscript.service.UserService;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 用户表Controller
 *
 * @author lsb
 * @version 1.0.0
 * @date 2021-02-02
 */
@RestController
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
@RequestMapping(value = "/api/User")
public class UserController {
    private static Logger logger = LoggerFactory.getLogger(UserController.class);
    /**
     * 用户表服务
     */
    @Autowired
    private UserService userService;
    /**
     * 用户菜单表服务
     */
    @Autowired
    private UserMenuService userMenuService;
    /**
     * Session Map
     */
    @Autowired
    private SessionMap sessionMap;
    //@Autowired
    //private HttpSessionMap httpSessionMap;
    /**
     * 新增用户表
     * UserVo  用户表VO
     *
     * @return Map
     */
    @RequestMapping(value = "insert", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> insert(HttpServletRequest request, @RequestBody UserVo userVo) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            Map<String, Object> hSesionMap = sessionMap.get(request.getHeader(ISystemConstant.SESSION_ID));
            //插入用户表(含校验)
            Map newUserMap = userService.insert(request, userVo);
            //插入用户菜单
            userMenuService.getGrantMenu(request, newUserMap);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "用户注册成功!");
            //更新session当前用户
            hSesionMap.put(ISystemConstant.CURRENT_USER, newUserMap);
            //更新当前token
            String token = StringHelper.getRandStr(7);
            hSesionMap.put(ISystemConstant.CURRENT_APP_TOKEN, token);
            result.put(ISystemConstant.CURRENT_APP_TOKEN, token);
            result.put(ISystemConstant.CURRENT_USER_ID, newUserMap.get("ID"));
            result.put(ISystemConstant.CURRENT_USER_NAME, newUserMap.get("USER_NAME"));
        } catch (Exception e) {
            logger.error("用户注册失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }


    /**
     * 更新用户表
     * UserVo  用户表VO
     *
     * @return Map
     */
    @RequestMapping(value = "update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> update(HttpServletRequest request, @RequestBody UserVo userVo) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            //更新用户表(含校验)
            userService.update(userVo);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "用户表成功!");
        } catch (Exception e) {
            logger.error("用户表失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }

    /**
     * 删除用户表
     * UserVo  用户表VO
     *
     * @return Map
     */
    @RequestMapping(value = "delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> delete(HttpServletRequest request, @RequestBody UserVo userVo) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            //更新用户表(含校验)
            userService.delete(userVo);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "用户表成功!");
        } catch (Exception e) {
            logger.error("用户表失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }

    /**
     * 根据id查询用户表
     *
     * @return Map<String   ,       Object>  应答Map
     */
    @RequestMapping(value = "getById", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> getById(HttpServletRequest request) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            String id = request.getParameter("id");
            Map m = userService.getById(id);

            //返回
            if (m == null) {
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "用户表数据没找到!");
            } else {
                result.put(ISystemConstant.AJAX_BEAN, m);
                result.put(ISystemConstant.AJAX_MESSAGE, "操作成功!");
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            }
        } catch (Exception e) {
            logger.error("getById失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "查询用户表数据失败!");
        }
        return result;

    }

    /**
     * 翻页查询用户表列表
     *
     * @param request
     * @return Map<String   ,       Object> 查询列表应答Map
     */
    @RequestMapping(value = "listPage", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> listPage(HttpServletRequest request) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            //TODO:获取查询条件
//            String userId = request.getParameter("userId");
//            if (StringHelper.isEmpty(userId))
//                throw new Exception("缺少参数:userId");
            //页号
            String strPageNo = request.getParameter(ISystemConstant.PAGE_NO);
            if (StringHelper.isEmpty(strPageNo))
                throw new Exception("缺少参数:" + ISystemConstant.PAGE_NO);
            //页大小
            String strPageSize = request.getParameter(ISystemConstant.PAGE_SIZE);
            if (StringHelper.isEmpty(strPageSize))
                throw new Exception("缺少参数:" + ISystemConstant.PAGE_SIZE);

            int pageNo = ConvertHelper.toInt(strPageNo);
            int pageSize = ConvertHelper.toInt(strPageSize);
            List<Map> list;
            logger.info("pageNo:" + pageNo);
            logger.info("pageSize:" + pageSize);
            Map<String, Object> searchMap;
            searchMap = new HashMap<String, Object>();
            //TODO 拼装条件
//            searchMap.put("OPER_USER_ID", userId);
            list = userService.listPage(searchMap, pageNo, pageSize);
            logger.info("list count:" + list.size());
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_LIST, list);
            result.put("count", userService.count(searchMap));
            result.put(ISystemConstant.AJAX_MESSAGE, "查询成功!");
        } catch (Exception e) {
            logger.error("用户表查询失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }

    /**
     * 生成验证码
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "getVerifyCode")
    public void getVerifyCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ServletOutputStream outputStream = response.getOutputStream();
        String sessionId = request.getParameter(ISystemConstant.SESSION_ID);
        logger.debug("sesionId:"+sessionId);
        Map<String,Object> hSessionMap = sessionMap.get(sessionId);
        if(hSessionMap==null){
            logger.error("无效的会话id");
            return;
        }
        //算术验证码 数字加减乘除. 建议2位运算就行:captcha.setLen(2);
//        ArithmeticCaptcha captcha = new ArithmeticCaptcha(120, 40);

        // 中文验证码
//        ChineseCaptcha captcha = new ChineseCaptcha(120, 40);

        // 英文与数字验证码
        SpecCaptcha captcha = new SpecCaptcha(120, 30);

        //英文与数字动态验证码
//        GifCaptcha captcha = new GifCaptcha(120, 40);

        // 几位数运算，默认是两位
        captcha.setLen(4);
        // 获取运算的结果
        String result = captcha.text();
        System.out.println(result);
//        Map<String,Object> hSessionMap = new HashMap<>();
//        hSessionMap.put(ISystemConstant.SESSION_ID,StringHelper.getUUID());
        //更新当前会话
        hSessionMap.put(ISystemConstant.CURRENT_VERIFY_CODE, result);
        //httpSessionMap.put((String)hSessionMap.get(ISystemConstant.SESSION_ID),hSessionMap);
        captcha.out(outputStream);
    }

    /**
     * 用户登录
     *
     * @return Map<String   ,       Object>  应答Map
     */
    @RequestMapping(value = "login", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> login(HttpServletRequest request, @RequestBody LoginVo loginVo) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            String userName = loginVo.getUserName();
            if (StringHelper.isEmpty(userName)) {
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "用户名为空!");
                return result;
            }
            String passWord = loginVo.getPassWord();
            if (StringHelper.isEmpty(passWord)) {
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "密码为空!");
                return result;
            }
            String verificationCode = loginVo.getVerificationCode();
            if (StringHelper.isEmpty(verificationCode)) {
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "验证码为空!");
                return result;
            }
            //比较验证码是否正确


            Map<String,Object> hSessionMap = sessionMap.get(request.getHeader(ISystemConstant.SESSION_ID));
            if(hSessionMap==null){
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "无效的会话id!");
                return result;
            }
            if (!verificationCode.equalsIgnoreCase((String) hSessionMap.get(ISystemConstant.CURRENT_VERIFY_CODE))) {
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "验证码错误!");
                return result;
            }
            Map<String, Object> searchMap = new HashMap<>();

            searchMap.put("USER_NAME", userName);
            List<Map> userList = userService.search(searchMap);
            if (userList == null || userList.isEmpty()) {
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "用户名或密码不正确!");
                return result;
            }
            if (!passWord.equals(userList.get(0).get("PASSWORD"))) {
                result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
                result.put(ISystemConstant.AJAX_MESSAGE, "用户名或密码不正确!");
                return result;
            }
            result.put(ISystemConstant.AJAX_MESSAGE, "登录成功!");
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            //更新session当前用户
            hSessionMap.put(ISystemConstant.CURRENT_USER, userList.get(0));
            //更新当前token
            String token = StringHelper.getRandStr(7);
            hSessionMap.put(ISystemConstant.CURRENT_APP_TOKEN, token);
            result.put(ISystemConstant.CURRENT_APP_TOKEN, token);
            result.put(ISystemConstant.CURRENT_USER_ID, userList.get(0).get("ID"));
            result.put(ISystemConstant.CURRENT_USER_NAME, userList.get(0).get("USER_NAME"));
            result.put(ISystemConstant.CREATE_TIME,new Date());
            hSessionMap.putAll(result);
        } catch (Exception e) {
            logger.error("logIn失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "登录失败!");
        }
        return result;

    }

    /**
     * 用户退出
     *
     * @return Map<String   ,       Object>  应答Map
     */
    @RequestMapping(value = "logout", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> logout(HttpServletRequest request) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {

            result.put(ISystemConstant.AJAX_MESSAGE, "退出登录成功!");
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            Map<String,Object> hSessionMap = sessionMap.get(request.getHeader(ISystemConstant.SESSION_ID));
            if(hSessionMap==null){
                return result;
            }
            //清空session当前用户
            sessionMap.remove(request.getHeader(ISystemConstant.SESSION_ID));
        } catch (Exception e) {
            logger.error("logout失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, "登出失败!");
        }
        return result;

    }

    /**
     * 响应错误消息
     * UserVo  用户表VO
     *
     * @return Map
     */
    @RequestMapping(value = "responseError", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> responseError(HttpServletRequest request, @RequestBody UserVo userVo) {
        Map<String, Object> result = new HashMap<String, Object>();
        String msg = request.getParameter("msg");
        String code = request.getParameter("code");
        result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
        result.put(ISystemConstant.AJAX_CODE, code);
        result.put(ISystemConstant.AJAX_MESSAGE, msg);

        return result;
    }
    /**
     * 重设用户密码
     * UserVo  用户表VO
     *
     * @return Map
     */
    @RequestMapping(value = "resetPassword", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> resetPassword(HttpServletRequest request, @RequestBody UserVo userVo) {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            //重置用户密码表(含校验)
            Map newUserMap = userService.resetPassword(request, userVo);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "重置密码成功!");
        } catch (Exception e) {
            logger.error("重设用户密码失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }
    /**
     * 产生新session
     * UserVo  用户表VO
     *
     * @return Map
     */
    @RequestMapping(value = "makeNewSession", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Map<String, Object> makeNewSession() {
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            Map<String,Object> smap = new HashMap<>();
            smap.put(ISystemConstant.SESSION_ID,StringHelper.getUUID());
            sessionMap.put((String)smap.get(ISystemConstant.SESSION_ID),smap);
            result.put(ISystemConstant.SESSION_ID,smap.get(ISystemConstant.SESSION_ID));
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_SUCCESS);
            result.put(ISystemConstant.AJAX_MESSAGE, "生成Session成功!");
        } catch (Exception e) {
            logger.error("生成session失败", e);
            result.put(ISystemConstant.AJAX_STATUS, ISystemConstant.AJAX_RESULT_FAIL);
            result.put(ISystemConstant.AJAX_MESSAGE, e.getMessage());
        }
        return result;
    }
}
